package org.developer.dynamic.infra.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
  * 数据源切面类
  *
  * @author yisheng.mikelv@foxmail.com 2020/3/5 15:29
  */
@Aspect
@Component
public class DynamicDataSourceAop {
    private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceAop.class);

    //在 注解DataSourceKey 之前调用该方法
    @Before("@annotation(ds)")
    public void changeDataSource(JoinPoint point, DataSourceKey ds){
        String dsId = ds.value();
        if(DynamicDataSourceContextHolder.dataSourceIds.contains(dsId)){
            //当日志级别为 debug 时输出
            //point.getSignature() 获取切入点的方法名
            logger.debug("Use DataSourceKey :{} >", dsId, point.getSignature());
            //设置数据源的 key
            DynamicDataSourceContextHolder.setDataSourceRouterKey(dsId);
        }else{
            //point.getSignature() 获取切入点的方法名
            logger.info("数据源[{}]不存在，使用默认数据源 >{}", dsId, point.getSignature());
        }
    }

    //在调用 注解DataSourceKey 之前调用该方法
    @After("@annotation(ds)")
    public void restoreDataSource(JoinPoint point, DataSourceKey ds){
        //当日志级别为 debug 时输出
        //point.getSignature() 获取切入点的方法名
        logger.debug("Revert DataSourceKey : " + ds.value() + " > " + point.getSignature());
        //移除 ThreadLocalMap 中存储的 ThreadLocal对象和值，避免内存溢出
        DynamicDataSourceContextHolder.removeDataSourceRouterKey();
    }
}
